home *** CD-ROM | disk | FTP | other *** search
- /***********************************************************
- Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
- The Netherlands.
-
- All Rights Reserved
-
- Permission to use, copy, modify, and distribute this software and its
- documentation for any purpose and without fee is hereby granted,
- provided that the above copyright notice appear in all copies and that
- both that copyright notice and this permission notice appear in
- supporting documentation, and that the names of Stichting Mathematisch
- Centrum or CWI not be used in advertising or publicity pertaining to
- distribution of the software without specific, written prior permission.
-
- STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
- THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
- FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
- ******************************************************************/
-
- /* Note: This file is partially converted to the new naming standard */
- /* ctbcm objects */
-
-
- #include "allobjects.h"
-
- #include "macglue.h"
-
- #include <CommResources.h>
- #include <Connections.h>
- #include <ToolUtils.h>
- #include <OSUtils.h>
-
- #ifndef HAVE_UNIVERSAL_HEADERS
- #define ConnectionCompletionUPP ProcPtr
- #define ConnectionChooseIdleUPP ProcPtr
- #define NewConnectionCompletionProc(x) (x)
- #define NewConnectionChooseIdleProc(x) (x)
- #endif
-
- #define _UnimplementedToolTrap 0xA89F
- #define _CommToolboxTrap 0x8B
- #define _UnimplementedOSTrap 0x9F
-
- extern object *PyErr_Mac(object *,int);
-
- static object *ErrorObject;
-
- typedef struct {
- OB_HEAD
- ConnHandle hdl; /* The handle to the connection */
- object *callback; /* Python callback routine */
- int has_callback; /* True if callback not None */
- int err; /* Error to pass to the callback */
- } ctbcmobject;
-
- staticforward typeobject ctbcmtype;
-
- #define is_ctbcmobject(v) ((v)->ob_type == &ctbcmtype)
-
- static
- TrapAvailable(short tNumber, TrapType tType)
- {
- short unImplemented;
-
- if (tType == OSTrap)
- unImplemented = _UnimplementedOSTrap;
- else
- unImplemented = _UnimplementedToolTrap;
-
- return NGetTrapAddress(tNumber, tType) != NGetTrapAddress(unImplemented, tType);
- }
-
- static
- initialize_ctb()
- {
- OSErr err;
- static initialized = -1;
-
- if ( initialized >= 0 )
- return initialized;
- initialized = 0;
-
- if ( !TrapAvailable(_CommToolboxTrap, OSTrap) ) {
- err_setstr(ErrorObject, "CTB not available");
- return 0;
- }
- if ( (err=InitCTBUtilities()) ) {
- PyErr_Mac(ErrorObject, (int)err);
- return 0;
- }
- if ( (err=InitCRM()) ) {
- PyErr_Mac(ErrorObject, (int)err);
- return 0;
- }
- if ( (err=InitCM()) ) {
- PyErr_Mac(ErrorObject, (int)err);
- return 0;
- }
- initialized = 1;
- return 1;
- }
-
- static int
- ctbcm_pycallback(arg)
- void *arg;
- {
- ctbcmobject *self = (ctbcmobject *)arg;
- object *args, *rv;
-
- if ( !self->has_callback ) /* It could have been removed in the meantime */
- return 0;
- args = mkvalue("(i)", self->err);
- rv = call_object(self->callback, args);
- DECREF(args);
- if( rv == NULL )
- return -1;
- DECREF(rv);
- return 0;
- }
-
- /*DBG*/int ncallback;
- static pascal void
- ctbcm_ctbcallback(hconn)
- ConnHandle hconn;
- {
- ctbcmobject *self;
-
- /* XXXX Do I have to do the A5 mumbo-jumbo? */
- ncallback++; /*DBG*/
- self = (ctbcmobject *)CMGetUserData(hconn);
- self->err = (int)((*hconn)->errCode);
- Py_AddPendingCall(ctbcm_pycallback, (void *)self);
- }
-
- static ctbcmobject *
- newctbcmobject(arg)
- object *arg;
- {
- ctbcmobject *self;
- self = NEWOBJ(ctbcmobject, &ctbcmtype);
- if (self == NULL)
- return NULL;
- self->hdl = NULL;
- INCREF(None);
- self->callback = None;
- self->has_callback = 0;
- return self;
- }
-
- /* ctbcm methods */
-
- static void
- ctbcm_dealloc(self)
- ctbcmobject *self;
- {
- if ( self->hdl ) {
- (void)CMClose(self->hdl, 0, (ConnectionCompletionUPP)0, 0, 1);
- /*XXXX Is this safe? */
- CMDispose(self->hdl);
- self->hdl = NULL;
- }
- DEL(self);
- }
-
- static object *
- ctbcm_open(self, args)
- ctbcmobject *self;
- object *args;
- {
- long timeout;
- OSErr err;
- ConnectionCompletionUPP cb_upp = NewConnectionCompletionProc(ctbcm_ctbcallback);
-
- if (!getargs(args, "l", &timeout))
- return NULL;
- if ( (err=CMOpen(self->hdl, self->has_callback, cb_upp, timeout)) < 0)
- return PyErr_Mac(ErrorObject, (int)err);
- INCREF(None);
- return None;
- }
-
- static object *
- ctbcm_listen(self, args)
- ctbcmobject *self;
- object *args;
- {
- long timeout;
- OSErr err;
- ConnectionCompletionUPP cb_upp = NewConnectionCompletionProc(ctbcm_ctbcallback);
-
- if (!getargs(args, "l", &timeout))
- return NULL;
- if ( (err=CMListen(self->hdl,self->has_callback, cb_upp, timeout)) < 0)
- return PyErr_Mac(ErrorObject, (int)err);
- INCREF(None);
- return None;
- }
-
- static object *
- ctbcm_accept(self, args)
- ctbcmobject *self;
- object *args;
- {
- int accept;
- OSErr err;
-
- if (!getargs(args, "i", &accept))
- return NULL;
- if ( (err=CMAccept(self->hdl, accept)) < 0)
- return PyErr_Mac(ErrorObject, (int)err);
- INCREF(None);
- return None;
- }
-
- static object *
- ctbcm_close(self, args)
- ctbcmobject *self;
- object *args;
- {
- int now;
- long timeout;
- OSErr err;
- ConnectionCompletionUPP cb_upp = NewConnectionCompletionProc(ctbcm_ctbcallback);
-
- if (!getargs(args, "(li)", &timeout, &now))
- return NULL;
- if ( (err=CMClose(self->hdl, self->has_callback, cb_upp, timeout, now)) < 0)
- return PyErr_Mac(ErrorObject, (int)err);
- INCREF(None);
- return None;
- }
-
- static object *
- ctbcm_read(self, args)
- ctbcmobject *self;
- object *args;
- {
- long timeout, len;
- int chan;
- CMFlags flags;
- OSErr err;
- object *rv;
- ConnectionCompletionUPP cb_upp = NewConnectionCompletionProc(ctbcm_ctbcallback);
-
- if (!getargs(args, "(lil)", &len, &chan, &timeout))
- return NULL;
- if ((rv=newsizedstringobject(NULL, len)) == NULL)
- return NULL;
- if ((err=CMRead(self->hdl, (Ptr)getstringvalue(rv), &len, (CMChannel)chan,
- self->has_callback, cb_upp, timeout, &flags)) < 0)
- return PyErr_Mac(ErrorObject, (int)err);
- resizestring(&rv, len);
- return mkvalue("(Oi)", rv, (int)flags);
- }
-
- static object *
- ctbcm_write(self, args)
- ctbcmobject *self;
- object *args;
- {
- long timeout, len;
- int chan, ilen, flags;
- OSErr err;
- char *buf;
- ConnectionCompletionUPP cb_upp = NewConnectionCompletionProc(ctbcm_ctbcallback);
-
- if (!getargs(args, "(s#ili)", &buf, &ilen, &chan, &timeout, &flags))
- return NULL;
- len = ilen;
- if ((err=CMWrite(self->hdl, (Ptr)buf, &len, (CMChannel)chan,
- self->has_callback, cb_upp, timeout, (CMFlags)flags)) < 0)
- return PyErr_Mac(ErrorObject, (int)err);
- return newintobject((int)len);
- }
-
- static object *
- ctbcm_status(self, args)
- ctbcmobject *self;
- object *args;
- {
- CMBufferSizes sizes;
- CMStatFlags flags;
- OSErr err;
- object *rv;
-
- if (!getnoarg(args))
- return NULL;
- if ((err=CMStatus(self->hdl, sizes, &flags)) < 0)
- return PyErr_Mac(ErrorObject, (int)err);
- rv = mkvalue("(llllll)", sizes[0], sizes[1], sizes[2], sizes[3], sizes[4], sizes[5]);
- if ( rv == NULL )
- return NULL;
- return mkvalue("(Ol)", rv, (long)flags);
- }
-
- static object *
- ctbcm_getconfig(self, args)
- ctbcmobject *self;
- object *args;
- {
- char *rv;
-
- if (!getnoarg(args))
- return NULL;
- if ((rv=(char *)CMGetConfig(self->hdl)) == NULL ) {
- err_setstr(ErrorObject, "CMGetConfig failed");
- return NULL;
- }
- return newstringobject(rv);
- }
-
- static object *
- ctbcm_setconfig(self, args)
- ctbcmobject *self;
- object *args;
- {
- char *cfg;
- OSErr err;
-
- if (!getargs(args, "s", &cfg))
- return NULL;
- if ((err=CMSetConfig(self->hdl, (Ptr)cfg)) < 0)
- return PyErr_Mac(ErrorObject, err);
- return newintobject((int)err);
- }
-
- static object *
- ctbcm_choose(self, args)
- ctbcmobject *self;
- object *args;
- {
- int rv;
- Point pt;
-
- if (!getnoarg(args))
- return NULL;
- pt.v = 40;
- pt.h = 40;
- rv=CMChoose(&self->hdl, pt, (ConnectionChooseIdleUPP)0);
- return newintobject(rv);
- }
-
- static object *
- ctbcm_idle(self, args)
- ctbcmobject *self;
- object *args;
- {
- if (!getnoarg(args))
- return NULL;
- CMIdle(self->hdl);
- INCREF(None);
- return None;
- }
-
- static object *
- ctbcm_abort(self, args)
- ctbcmobject *self;
- object *args;
- {
- if (!getnoarg(args))
- return NULL;
- CMAbort(self->hdl);
- INCREF(None);
- return None;
- }
-
- static object *
- ctbcm_reset(self, args)
- ctbcmobject *self;
- object *args;
- {
- if (!getnoarg(args))
- return NULL;
- CMReset(self->hdl);
- INCREF(None);
- return None;
- }
-
- static object *
- ctbcm_break(self, args)
- ctbcmobject *self;
- object *args;
- {
- long duration;
- ConnectionCompletionUPP cb_upp = NewConnectionCompletionProc(ctbcm_ctbcallback);
-
- if (!getargs(args, "l", &duration))
- return NULL;
- CMBreak(self->hdl, duration,self->has_callback, cb_upp);
- INCREF(None);
- return None;
- }
-
- static struct methodlist ctbcm_methods[] = {
- {"Open", (method)ctbcm_open},
- {"Close", (method)ctbcm_close},
- {"Read", (method)ctbcm_read},
- {"Write", (method)ctbcm_write},
- {"Status", (method)ctbcm_status},
- {"GetConfig", (method)ctbcm_getconfig},
- {"SetConfig", (method)ctbcm_setconfig},
- {"Choose", (method)ctbcm_choose},
- {"Idle", (method)ctbcm_idle},
- {"Listen", (method)ctbcm_listen},
- {"Accept", (method)ctbcm_accept},
- {"Abort", (method)ctbcm_abort},
- {"Reset", (method)ctbcm_reset},
- {"Break", (method)ctbcm_break},
- {NULL, NULL} /* sentinel */
- };
-
- static object *
- ctbcm_getattr(self, name)
- ctbcmobject *self;
- char *name;
- {
- if ( strcmp(name, "callback") == 0 ) {
- INCREF(self->callback);
- return self->callback;
- }
- return findmethod(ctbcm_methods, (object *)self, name);
- }
-
- static int
- ctbcm_setattr(self, name, v)
- ctbcmobject *self;
- char *name;
- object *v;
- {
- if ( strcmp(name, "callback") != 0 ) {
- err_setstr(AttributeError, "ctbcm objects have callback attr only");
- return -1;
- }
- if ( v == NULL ) {
- v = None;
- }
- INCREF(v); /* XXXX Must I do this? */
- self->callback = v;
- self->has_callback = (v != None);
- return 0;
- }
-
- statichere typeobject ctbcmtype = {
- OB_HEAD_INIT(&Typetype)
- 0, /*ob_size*/
- "ctbcm", /*tp_name*/
- sizeof(ctbcmobject), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- /* methods */
- (destructor)ctbcm_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- (getattrfunc)ctbcm_getattr, /*tp_getattr*/
- (setattrfunc)ctbcm_setattr, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash*/
- };
- /* --------------------------------------------------------------------- */
-
- /* Function of no arguments returning new ctbcm object */
-
- static object *
- ctb_cmnew(self, args)
- object *self; /* Not used */
- object *args;
- {
- int strlen;
- object *sizes_obj;
- char *c_str;
- unsigned char p_str[255];
- CMBufferSizes sizes;
- short procid;
- ConnHandle hdl;
- ctbcmobject *rv;
-
- if (!getargs(args, "(s#O)", &c_str, &strlen, &sizes_obj))
- return NULL;
- strncpy((char *)p_str+1, c_str, strlen);
- p_str[0] = strlen;
- if (!initialize_ctb())
- return NULL;
- if ( sizes_obj == None ) {
- memset(sizes, '\0', sizeof sizes);
- } else {
- if ( !getargs(sizes_obj, "(llllll)", &sizes[0], &sizes[1], &sizes[2],
- &sizes[3], &sizes[4], &sizes[5]))
- return NULL;
- }
- if ( (procid=CMGetProcID(p_str)) < 0 )
- return PyErr_Mac(ErrorObject, procid);
- hdl = CMNew(procid, cmNoMenus|cmQuiet, sizes, 0, 0);
- if ( hdl == NULL ) {
- err_setstr(ErrorObject, "CMNew failed");
- return NULL;
- }
- rv = newctbcmobject(args);
- if ( rv == NULL )
- return NULL; /* XXXX Should dispose of hdl */
- rv->hdl = hdl;
- CMSetUserData(hdl, (long)rv);
- return (object *)rv;
- }
-
- static object *
- ctb_available(self, args)
- object *self;
- object *args;
- {
- int ok;
-
- if (!getnoarg(args))
- return NULL;
- ok = initialize_ctb();
- err_clear();
- return newintobject(ok);
- }
-
- /* List of functions defined in the module */
-
- static struct methodlist ctb_methods[] = {
- {"CMNew", ctb_cmnew},
- {"available", ctb_available},
- {NULL, NULL} /* sentinel */
- };
-
-
- /* Initialization function for the module (*must* be called initctb) */
-
- void
- initctb()
- {
- object *m, *d, *o;
-
- /* Create the module and add the functions */
- m = initmodule("ctb", ctb_methods);
-
- /* Add some symbolic constants to the module */
- d = getmoduledict(m);
-
- #define CMCONST(name, value) o = newintobject(value); dictinsert(d, name, o)
-
- CMCONST("cmData", 1);
- CMCONST("cmCntl", 2);
- CMCONST("cmAttn", 3);
-
- CMCONST("cmFlagsEOM", 1);
-
- CMCONST("chooseDisaster", -2);
- CMCONST("chooseFailed", -1);
- CMCONST("chooseAborted", 0);
- CMCONST("chooseOKMinor", 1);
- CMCONST("chooseOKMajor", 2);
- CMCONST("chooseCancel", 3);
-
- CMCONST("cmStatusOpening", 1);
- CMCONST("cmStatusOpen", 2);
- CMCONST("cmStatusClosing", 4);
- CMCONST("cmStatusDataAvail", 8);
- CMCONST("cmStatusCntlAvail", 0x10);
- CMCONST("cmStatusAttnAvail", 0x20);
- CMCONST("cmStatusDRPend", 0x40);
- CMCONST("cmStatusDWPend", 0x80);
- CMCONST("cmStatusCWPend", 0x100);
- CMCONST("cmStatusCWPend", 0x200);
- CMCONST("cmStatusARPend", 0x400);
- CMCONST("cmStatusAWPend", 0x800);
- CMCONST("cmStatusBreakPending", 0x1000);
- CMCONST("cmStatusListenPend", 0x2000);
- CMCONST("cmStatusIncomingCallPresent", 0x4000);
-
- ErrorObject = newstringobject("ctb.error");
- dictinsert(d, "error", ErrorObject);
-
- /* Check for errors */
- if (err_occurred())
- fatal("can't initialize module ctb");
- }
-